package cn.yerly.sakura.monitor;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogMonitor {
	private final Logger logger = LoggerFactory.getLogger(LogMonitor.class);

	@AfterReturning(pointcut = "execution(* cn.yerly.sakura.service..*Service.*(..))", returning = "result")
	public void afterReturn(JoinPoint joinPoint, Object result) {
		logger.info("completed: " + getInvokeInfo(joinPoint) + " return:"
				+ result);
	}
	
	@AfterThrowing(pointcut = "execution(* cn.yerly.sakura.service..*Service.*(..))", throwing = "throwable")
	public void afterThrowing(JoinPoint joinPoint, Throwable throwable) throws Throwable {
		logger.error("throw: " + getInvokeInfo(joinPoint) + " exception:"
				+ throwable.getMessage());
		throw throwable;
	}

	@Before(value = "execution(* cn.yerly.sakura.service..*Service.*(..))")
	public void before(JoinPoint joinPoint) {
		logger.info("before: " + getInvokeInfo(joinPoint));
	}

	private String getInvokeInfo(JoinPoint joinPoint) {
		StringBuilder builder = new StringBuilder();
		builder.append(joinPoint.getTarget().getClass());
		builder.append(" method:").append(joinPoint.getSignature().getName());
		builder.append(" args:");
		Object[] args = joinPoint.getArgs();
		if (args != null && args.length > 0) {
			for (Object object : args) {
				builder.append(object).append(",");
			}
			builder.deleteCharAt(builder.length() - 1);
		}
		return builder.toString();
	}
}
